﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="SettingsFileOptionsForm.cs" company="Roman '4ux-nbIx' Novitsky">
//   Copyright (c) Roman '4ux-nbIx' Novitsky 2009
// </copyright>
// <summary>
//   Defines the SettingsFileOptionsForm type.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace SettingsManager
{
  #region Namespace Imports

  using System;
  using System.Collections.Generic;
  using System.Windows.Forms;

  using ComponentSettingsManagers;

  using JetBrains.Annotations;
  using JetBrains.Util;

  using MessageBox = JetBrains.Util.MessageBox;

  using System.Linq;

  #endregion


  /// <summary>
  /// Describes and manipulates the settings file options form.
  /// </summary>
  internal sealed partial class SettingsFileOptionsForm : Form
  {
    #region Constants and Fields

    private readonly SettingsFile _settingsFile;
    private bool _isNewExternalFileCreated;
    private SettingsManagerOptionsForm _settingsManagerOptionsForm;
    private Dictionary<string, object> _settingsManagersOptions;

    #endregion


    #region Constructors and Destructors

    /// <summary>
    /// Initializes a new instance of the <see cref="SettingsFileOptionsForm"/> class.
    /// </summary>
    /// <param name="settingsFile">
    /// The settings file.
    /// </param>
    public SettingsFileOptionsForm([NotNull] SettingsFile settingsFile)
    {
      _settingsFile = settingsFile;
      InitializeComponent();

      _autoupdateSettingsCheckBox.Checked = settingsFile.AutoUpdateCommonSettings;
      _clearReadOnlyFlag.Checked = settingsFile.ClearReadOnlyFlagOnUpdates;

      FileSystemPath externalSettingsContainerFilePath = settingsFile.ExternalSettingsContainerFilePath;

      _settingsGroupsListBox.SelectedSettingsManagers = settingsFile.SettingsManagers;

      if (externalSettingsContainerFilePath != null)
      {
        _storedInAFileCheckBox.Checked = true;
        _absolutePathCheckBox.Checked = externalSettingsContainerFilePath.IsAbsolute;
        _settingsFilePathTextBox.Text = externalSettingsContainerFilePath.FullPath;
      }

      _settingsManagersOptions = _settingsFile.SettingsManagersOptions.ToDictionary(p => p.Key, p => p.Value);

      UpdateControls();
    }

    #endregion


    #region Methods

    private void OnAbsolutePathCheckBoxCheckedChanged([NotNull] object sender, [NotNull] EventArgs e)
    {
      if (string.IsNullOrEmpty(_settingsFilePathTextBox.Text))
      {
        return;
      }

      UpdateSettingsFilePath();
    }


    private void OnBrowseButtonClick([NotNull] object sender, [NotNull] EventArgs e)
    {
      DialogResult dialogResult = _openSettingsFileDialog.ShowDialog(this);

      if (dialogResult != DialogResult.OK)
      {
        return;
      }

      _settingsFilePathTextBox.Text = _openSettingsFileDialog.FileName;
      _isNewExternalFileCreated = false;

      UpdateSettingsFilePath();
    }


    private void OnCheckBoxCheckedChanged([NotNull] object sender, [NotNull] EventArgs e)
    {
      UpdateControls();
    }


    private void OnConfigureSettingsManagerButtonClick([NotNull] object sender, [NotNull] EventArgs e)
    {
      if (_settingsManagerOptionsForm == null || _settingsGroupsListBox.SelectedSettingsManager == null)
      {
        return;
      }

      object options = null;

      var componentTagName = _settingsGroupsListBox.SelectedSettingsManager.ComponentTagName;

      if (_settingsManagersOptions.ContainsKey(componentTagName))
      {
        options = _settingsManagersOptions[componentTagName];
      }

      _settingsManagerOptionsForm.Options = options;
      var result = _settingsManagerOptionsForm.ShowDialog(this);

      if (result != DialogResult.OK)
      {
        return;
      }

      if (_settingsManagerOptionsForm.Options == null)
      {
        _settingsManagersOptions.Remove(componentTagName);
        return;
      }

      _settingsManagersOptions[componentTagName] = _settingsManagerOptionsForm.Options;
    }


    private void OnCreateExternalFileButtonClick([NotNull] object sender, [NotNull] EventArgs e)
    {
      DialogResult dialogResult = _saveFileDialog.ShowDialog(this);

      if (dialogResult != DialogResult.OK)
      {
        return;
      }

      _settingsFilePathTextBox.Text = _saveFileDialog.FileName;
      _isNewExternalFileCreated = true;

      UpdateSettingsFilePath();
    }


    private void OnOkButtonClick([NotNull] object sender, [NotNull] EventArgs e)
    {
      _settingsFile.AutoUpdateCommonSettings = _autoupdateSettingsCheckBox.Checked;
      _settingsFile.ClearReadOnlyFlagOnUpdates = _clearReadOnlyFlag.Checked;

      if (_storedInAFileCheckBox.Checked)
      {
        if (string.IsNullOrEmpty(_settingsFilePathTextBox.Text))
        {
          MessageBox.ShowError("Invalid external settings file path.", "Error", Handle);
          return;
        }

        _settingsFile.ExternalSettingsContainerFilePath = new FileSystemPath(_settingsFilePathTextBox.Text);
      }
      else
      {
        _settingsFile.ExternalSettingsContainerFilePath = null;
      }

      _settingsFile.SettingsManagers = _settingsGroupsListBox.SelectedSettingsManagers;
      _settingsFile.SettingsManagersOptions.Clear();

      foreach (KeyValuePair<string, object> options in _settingsManagersOptions)
      {
        _settingsFile.SettingsManagersOptions.Add(options.Key, options.Value);
      }

      _settingsFile.SaveContents();

      if (_storedInAFileCheckBox.Checked && _isNewExternalFileCreated)
      {
        var sharedSettingsFile = _settingsFile as SharedSettingsFile;

        if (sharedSettingsFile != null)
        {
          sharedSettingsFile.SaveResharperSettings(false);
        }
        else
        {
          _settingsFile.SaveResharperSettings();
        }
      }

      DialogResult = DialogResult.OK;
    }


    private void OnSettingsGroupsListBoxSelectedIndexChanged([NotNull] object sender, [NotNull] EventArgs e)
    {
      if (_settingsManagerOptionsForm != null)
      {
        _settingsManagerOptionsForm.Dispose();
        _settingsManagerOptionsForm = null;
      }

      IComponentSettingsManager settingsManager = _settingsGroupsListBox.SelectedSettingsManager;

      if (settingsManager != null)
      {
        _settingsManagerOptionsForm = settingsManager.GetOptionsForm();
      }

      _configureSettingsManagerButton.Enabled = _settingsManagerOptionsForm != null;
    }


    private void OnStoredInAFileCheckBoxCheckedChanged([NotNull] object sender, [NotNull] EventArgs e)
    {
      UpdateControls();
    }


    private void UpdateControls()
    {
      bool storedInAFileChecked = _storedInAFileCheckBox.Checked;

      _browseButton.Enabled = storedInAFileChecked;
      _createExternalFileButton.Enabled = storedInAFileChecked;
      _absolutePathCheckBox.Enabled = storedInAFileChecked;
    }


    private void UpdateSettingsFilePath()
    {
      if (_absolutePathCheckBox.Checked)
      {
        var filePath = new FileSystemPath(_settingsFilePathTextBox.Text);

        if (filePath.IsAbsolute)
        {
          return;
        }

        FileSystemPath absolutePath = _settingsFile.Path.Directory.Combine(filePath);
        _settingsFilePathTextBox.Text = absolutePath.FullPath;
      }
      else
      {
        var filePath = new FileSystemPath(_settingsFilePathTextBox.Text);
        FileSystemPath relativePath = filePath.ConvertToRelativePath(_settingsFile.Path.Directory);

        _settingsFilePathTextBox.Text = relativePath.FullPath;
      }
    }

    #endregion
  }
}